#include <utility>
#include <string>

using namespace std;

class StrVec {
    public:
        StrVec(StrVec&&) noexcept; // 移动构造函数
        StrVec& operator=(StrVec&&) noexcept; // 移动赋值运算符
    private:
        void free();                    // 销毁元素并释放内存
        string *elements;               // 指向数组首元素的指针
        string *first_free;             // 指向数组第一个空闲元素的指针
        string *cap;                    // 指向数组尾后位置的指针
};

/**
 * noexcept 承诺一个函数不抛出异常
 * 移动构造函数和移动赋值运算符必须标记为 noexcept
 * 移后源对象必须可析构
 */

StrVec::StrVec(StrVec &&s) noexcept
    // 成员初始化器接管 s 中的资源
    : elements(s.elements), first_free(s.first_free), cap(s.cap)
{
    // 令 s 进入这样的状态————对其运行析构函数是安全的
    s.elements = s.first_free = s.cap = nullptr;
}

StrVec& StrVec::operator=(StrVec&& rhs) noexcept
{
    // 直接检测自赋值
    if (this != &rhs) {
        free();                  // 释放已有元素
        elements = rhs.elements; // 从 rhs 接管资源
        first_free = rhs.first_free;
        cap = rhs.cap;
        // 将 rhs 置于可析构状态
        rhs.elements = rhs.first_free = rhs.cap = nullptr;
    }
    return *this;
}